/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Autogenerated file. DO NOT EDIT

package std.interop.js;

// NOTE(zhaoziming_hw): #IC8LO3 remove local declaration after Any type is supported
type Any = Object | null | undefined;

export final class InteropTransferHelper {
    private static native transferArrayBufferToStaticImpl(dynamicESValue: ESValue): ArrayBuffer;
    public static transferArrayBufferToStatic(dynamicObject: Any): Object {
        if (dynamicObject == null || dynamicObject == undefined) {
            throw new Error("dynamicObject is null or undefined");
        }
        let dynamicESValue = ESValue.wrap(__narrowAny<object>(dynamicObject));
        return InteropTransferHelper.transferArrayBufferToStaticImpl(dynamicESValue) as Object;
    }

    private static native transferArrayBufferToDynamicImpl(staticObject: ArrayBuffer): Any;
    public static transferArrayBufferToDynamic(staticObject: Object): Any {
        return InteropTransferHelper.transferArrayBufferToDynamicImpl(staticObject as ArrayBuffer);
    }

    private static native createDynamicTypedArray(buffer: ArrayBuffer, typedArrayType: int, length: double,
                                                  byteOffset: double): Any;

    private static native createDynamicDataView(buffer: ArrayBuffer, byteLength: double, byteOffset: double): Any;
{#- NOTE: the following sequence must follow the sequence of napi_typedarray_type #}
{% set typed_arrays = [
    { "type_name": "Int8Array" },
    { "type_name": "Uint8Array" },
    { "type_name": "Uint8ClampedArray" },
    { "type_name": "Int16Array" },
    { "type_name": "Uint16Array" },
    { "type_name": "Int32Array" },
    { "type_name": "Uint32Array" },
    { "type_name": "Float32Array" },
    { "type_name": "Float64Array" },
    { "type_name": "BigInt64Array" },
    { "type_name": "BigUint64Array" }
]-%}
{%- for typed_array in typed_arrays %}

    public static transfer{{ typed_array.type_name }}ToStatic(dynamicObject: Any): Object {
        if (dynamicObject == null || dynamicObject == undefined) {
            throw new Error("dynamicObject is null or undefined");
        }

        let dynamicESValue = ESValue.wrap(__narrowAny<object>(dynamicObject));
        let dynamicBuffer = dynamicESValue.getProperty("buffer");
        let byteOffset = dynamicESValue.getProperty("byteOffset").toNumber();
        let length = dynamicESValue.getProperty("length").toNumber();

        let staticBuffer = InteropTransferHelper.transferArrayBufferToStaticImpl(dynamicBuffer);
        return new {{ typed_array.type_name }}(staticBuffer, byteOffset, length) as Object;
    }

    public static transfer{{ typed_array.type_name }}ToDynamic(staticObject: Object): Any {
        let staticTypedArray = staticObject as {{ typed_array.type_name }};

        let staticBuffer = staticTypedArray.buffer;
        if(staticBuffer instanceof ArrayBuffer == false) {
            throw new Error("staticObject.buffer is not an instance of ArrayBuffer");
        }

        let byteOffset = staticTypedArray.byteOffset;
        let length = staticTypedArray.length;

        let dynamicTypedArray = InteropTransferHelper.createDynamicTypedArray(
            staticBuffer as ArrayBuffer,
            {{ loop.index0 }},
            length,
            byteOffset
        );
        return dynamicTypedArray;
    }
{%- endfor %}

    public static transferDataViewToStatic(dynamicObject: Any): Object {
        if (dynamicObject == null || dynamicObject == undefined) {
            throw new Error("dynamicObject is null or undefined");
        }

        let dynamicESValue = ESValue.wrap(__narrowAny<object>(dynamicObject));
        let dynamicBuffer = dynamicESValue.getProperty("buffer");
        let byteOffset = dynamicESValue.getProperty("byteOffset").toNumber();
        let byteLength = dynamicESValue.getProperty("byteLength").toNumber();

        let staticBuffer = InteropTransferHelper.transferArrayBufferToStaticImpl(dynamicBuffer);
        return new DataView(staticBuffer, byteOffset, byteLength) as Object;
    }

    public static transferDataViewToDynamic(staticObject: Object): Any {
        let staticDataView = staticObject as DataView;

        let staticBuffer = staticDataView.buffer;
        if(staticBuffer instanceof ArrayBuffer == false) {
            throw new Error("staticObject.buffer is not an instance of ArrayBuffer");
        }

        let byteOffset = staticDataView.byteOffset;
        let byteLength = staticDataView.byteLength;

        let dynamicDataView = InteropTransferHelper.createDynamicDataView(staticBuffer as ArrayBuffer, byteLength, byteOffset);
        return dynamicDataView;
    }
}